#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;

bool setup(int argc, char* argv[]);
void generate();

string symbols = "!#$0123456789=?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
unsigned int length, num;

int main(int argc, char* argv[]) {
    if(setup(argc, argv)) {
        generate();
        return 0;
    } else {
        cout << "Usage: passgen [ARGUMENTS]" << endl << "Arguments:\n-h    show this message\n-l    custom length\n-c    custom list of symbols\n";
        return 1;
    }
}

bool setup(int argc, char* argv[]) {
    for (uint8_t a = 1; a < argc; a+=2) {
        if (!strcmp(argv[a], "-h")) {
            return false;
        } else if ((argc == a + 2 || argc == a + 4) && !strcmp(argv[a], "-l")) {
            length = atoi(argv[a + 1]);
        } else if ((argc == a + 2 || argc == a + 4) && !strcmp("-c", argv[a])) {
            symbols = argv[a + 1];
        } else {
            return false;
        }
    }
    if (length == 0) {
        length = 32;
    }
    return true;
}


void generate() {
    ifstream urandom("/dev/urandom", ios::in|ios::binary);
    if (!urandom.is_open()) {
        cout << "urandom initial error!" << endl;
        exit(1);
    }
    for (unsigned int c = 0; c < length; c++) {
        urandom.read(reinterpret_cast<char*>(&num), sizeof(num));
        cout << symbols[num%symbols.length()];
    }
    cout << endl;
    urandom.close();
}
